package com.example.identifyvisio.service;

import com.example.identifyvisio.model.R;
import com.example.identifyvisio.model.component.Position;
import com.example.identifyvisio.model.connect.*;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import java.util.*;

import static com.example.identifyvisio.service.NodeService.getStart;
import static com.example.identifyvisio.service.NodeService.getSucceed;
import static com.example.identifyvisio.utis.NodeValueUtil.getRelationship;
import static com.example.identifyvisio.utis.NodeValueUtil.getToPart;

/**
 * 连接线
 */
public class ConnectService {
    /*
    连接线获取信息
     */
    public static R<Connect> getConnect(HashMap<Integer, Map<String, String>> dataMap,
                                       Integer shapeID, Map<String, String> shapeMap,
                                       NodeList shapeConnect, ArrayList<Object> shapes,
                                       HashMap<String, List<Position>> positionMap) {

        Connect connect = new Connect();
        connect.setShape("edge");

        Line line = new Line();
        line.setStroke("#323232");
        line.setStrokeWidth(1.2);
        line.setTargetMarker(new TargetMarker("block",
                6,4,-4));
        connect.setAttrs(new Attrs(line));

        String uniqueID = shapeMap.get("UniqueID");
        connect.setId(uniqueID);

        ConnectData connectData = new ConnectData();
        connectData.setStateType("edge");
        connectData.setLabel(shapeMap.get("text"));
        connect.setData(connectData);
        connect.setZIndex("-1");

        ArrayList<Labels> labelsArrayList = new ArrayList<>();
        getLabels(shapeMap, labelsArrayList);
        connect.setLabels(labelsArrayList);

        R<Connect> connectR = new R<>();
        //获取连接节点信息
        getConnectivityNode(dataMap, shapeID, shapeMap, shapeConnect, shapes, connect, positionMap,connectR);

        List<String> matches = getRelationship(shapeMap.get("relationships"));
        for (String match : matches) {
            if (dataMap.containsKey(Integer.valueOf(match))){
                Map<String, String> stringMap = dataMap.get(Integer.valueOf(match));
                connect.setParent(stringMap.get("UniqueID"));
            }
        }
        connectR.setData(connect);
        return connectR;
    }

    /**
     * 获取连接节点
     * @param dataMap
     * @param shapeID
     * @param shapeMap
     * @param shapeConnect
     * @param shapes
     * @param connect
     */
    private static void getConnectivityNode(HashMap<Integer, Map<String, String>> dataMap, Integer shapeID,
                                            Map<String, String> shapeMap, NodeList shapeConnect,
                                            ArrayList<Object> shapes, Connect connect,
                                            HashMap<String, List<Position>> positionMap,
                                            R<Connect> connectR) {
        //连接点信息
        double BeginX = Double.parseDouble(shapeMap.get("BeginX"));
        double BeginY = Double.parseDouble(shapeMap.get("BeginY"));
        double EndX = Double.parseDouble(shapeMap.get("EndX"));
        double EndY = Double.parseDouble(shapeMap.get("EndY"));
        //判断连接线是否连接到节点
        boolean existEndX = false,existBeginX = false;
        //连接线开始、结束点
        Map<String, String> endMap = null;
        Map<String, String> beginMap = null;
        for (int i = 0; i < shapeConnect.getLength(); i++) {
            Element connectElement = (Element) shapeConnect.item(i);
            Integer fromSheetId = Integer.valueOf(connectElement.getAttribute("FromSheet"));
            if (shapeID .equals(fromSheetId) ){
                String fromCell = connectElement.getAttribute("FromCell");

                Integer toSheetId = Integer.valueOf(connectElement.getAttribute("ToSheet"));

                Map<String, String> stringMap = dataMap.get(toSheetId);
                double pinX = Double.parseDouble(stringMap.get("PinX"));
                double PinY = Double.parseDouble(stringMap.get("PinY"));

                if ("EndX".equals(fromCell)){
                    existEndX = true;

                    endMap = stringMap;
                    String extracted = getToPart(pinX,PinY,EndX,EndY);
                    connect.setTarget( new Start(stringMap.get("UniqueID"), extracted));
                }else if ("BeginX".equals(fromCell)){
                    existBeginX = true;
                    beginMap = stringMap;

                    String extracted = getToPart(pinX,PinY,BeginX,BeginY);
                    connect.setSource(new Start(stringMap.get("UniqueID"), extracted));
                }
            }
        }
        if (!existEndX && !existBeginX){
            connectR.setMsg("连接线未连接到节点，需要手动删除");
            return;
        }
        //连接线空结尾默认连成功节点
        if (!existEndX){
            connectR.setMsg("连接线没有终点，默认连接到成功节点");
            //传入存在的节点，获取父节点坐标，从而定位默认创建的节点坐标
            String target = getSucceed(dataMap, beginMap, EndX, EndY, shapes,positionMap);
            connect.setTarget(new Start( target, "port3"));
        }
        //连接线空起始默认连开始节点
        if (!existBeginX){
            connectR.setMsg("连接线没有起点，默认从开始节点出发");
            String start = getStart(dataMap, endMap, BeginX, BeginY, shapes, positionMap);
            connect.setSource(new Start( start, "port4"));
        }
    }

    /**
     * 获取连接线的Labels属性
     * @param shapeMap
     * @param labelsArrayList
     */
    private static void getLabels(Map<String, String> shapeMap, ArrayList<Labels> labelsArrayList) {
        Labels labels = new Labels();
        ArrayList<Markup> markupArrayList = new ArrayList<>();
        Markup rectMarkup = new Markup();
        rectMarkup.setTagName("rect");
        rectMarkup.setSelector("labelBody");
        markupArrayList.add(rectMarkup);

        Markup textMarkup = new Markup();
        textMarkup.setTagName("text");
        textMarkup.setSelector("labelText");
        markupArrayList.add(textMarkup);

        labels.setMarkup(markupArrayList);

        LabelsAttrs labelsAttrs = new LabelsAttrs();
        HashMap<String, String> labelText = new HashMap<>();
        labelText.put("text", shapeMap.get("text"));
        labelText.put("fill","#ffa940");
        labelText.put("textAnchor","middle");
        labelText.put("textVerticalAnchor","middle");
        labelText.put("fontSize","8");

        HashMap<String, String> labelBody = new HashMap<>();
        labelBody.put("ref","labelText");
        labelBody.put("refX","0");
        labelBody.put("refY","1");
        labelBody.put("refWidth","100%");
        labelBody.put("refHeight","100%");
        labelBody.put("refWidth2","3");
        labelBody.put("refHeight2","1");

        labelsAttrs.setLabelText(labelText);
        labelsAttrs.setLabelBody(labelBody);

        labels.setAttrs(labelsAttrs);

        com.example.identifyvisio.model.connect.Position position = new com.example.identifyvisio.model.connect.Position();
        position.setDistance(0.3);
        Args args = new Args(true, true);
        position.setArgs(args);

        labels.setPosition(position);
        labelsArrayList.add(labels);
    }
}
